package com.hlg.xboot.web.controller;

import com.digi_zones.common.aliyun.oss.OSSService;
import com.digi_zones.common.utils.CommonUtils;
import com.hlg.xboot.core.media.VideoInfo;
import com.hlg.xboot.core.media.VideoThumbTaker;
import com.hlg.xboot.enums.ResourceType;
import com.hlg.xboot.exceptions.ParameterException;
import com.hlg.xboot.exceptions.ServerBizException;
import com.hlg.xboot.exceptions.UploadException;
import com.hlg.xboot.model.Resource;
import com.hlg.xboot.service.ResourceService;
import com.hlg.xboot.vo.RestBody;
import com.xiaoleilu.hutool.http.HttpRequest;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;

/**
 * Created by yangxin on 2017/5/3.
 */
@RestController
@RequestMapping("/resource")
public class ResourceController extends BaseController {

    @Autowired
    private ResourceService resourceService;

    @Autowired
    private OSSService ossService;

    /**
     * 上传资源
     * @param file 资源
     * @param type 资源类型
     * @see ResourceType
     * @return
     * @throws Exception
     */
    @RequestMapping(method = RequestMethod.POST)
    public RestBody upload(@RequestParam("file") MultipartFile file, Integer type) throws Exception {
        if (file == null) {
            throw new ParameterException("无效的资源");
        }

        String fileName = CommonUtils.genRandomeFileName(file.getOriginalFilename());
        String dir;
        MimeType mimeType = MimeTypeUtils.parseMimeType(file.getContentType());
        if (mimeType == null) {
            dir = appConfig.getAliyun().getBucket().getFiles();
            type = ResourceType.FILE.getValue();
        } else {
            switch (mimeType.getType()) {
                case "image":
                    dir = appConfig.getAliyun().getBucket().getImages();
                    type = ResourceType.IMAGE.getValue();
                    break;
                case "video":
                    dir = appConfig.getAliyun().getBucket().getVideos();
                    type = ResourceType.VIDEO.getValue();
                    break;
                case "audio":
                    dir = appConfig.getAliyun().getBucket().getAudios();
                    type = ResourceType.AUDIO.getValue();
                    break;
                default:
                    dir = appConfig.getAliyun().getBucket().getFiles();
                    type = ResourceType.FILE.getValue();
                    break;
            }
        }
        String url = ossService.upload(file.getInputStream(), dir,fileName);
        if (StringUtils.isEmpty(url)) {
            throw new UploadException();
        }
        Resource resource = new Resource(file.getOriginalFilename(), url);
        resource.setType(type);
        resource.setMimeType(file.getContentType());
        resource.setSize(file.getSize());
        if (ResourceType.VIDEO.getValue().equals(type)) {
            VideoInfo videoInfo = new VideoInfo(url);
            videoInfo.loadVideoInfo();
            resource.setWidth(videoInfo.getWidth());
            resource.setHeight(videoInfo.getHeight());
            resource.setDuration(videoInfo.getDuration());
            VideoThumbTaker thumbTaker = new VideoThumbTaker(url);
            String thumbFileName = FilenameUtils.getBaseName(fileName) + ".png";
            String cover = "/tmp/" + thumbFileName;
            thumbTaker.loadFirstThumb(cover,videoInfo.getWidth(), videoInfo.getHeight());
            File coverFile = new File(cover);
            if (coverFile.exists()) {
                String coverUrl = ossService.uploadImage(new FileInputStream(coverFile), thumbFileName);
                resource.setCover(coverUrl);
            }
        }
        resource = resourceService.add(resource);
        if (resource.getId() == null) {
            logger.error("上传失败,资源ID为空!");
            throw new UploadException("上传失败");
        }
        return success(resource);
    }

    /**
     * 删除资源
     * @param id 资源ID
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
    public RestBody delete(@PathVariable Serializable id) throws Exception {
        try {
            Resource resource = resourceService.delete(id);
            if (StringUtils.isNotEmpty(resource.getUrl())) {
                ossService.delete(resource.getUrl());
            }
        } catch (Exception e) {}

        return success();
    }

    @GetMapping(value = "/{id}")
    public RestBody get(@PathVariable Serializable id, HttpServletRequest request, HttpServletResponse response) throws Exception {
        return success(resourceService.findById(id));
    }

    @GetMapping("/download/{id}/{filename}")
    public ResponseEntity<byte[]> download(@PathVariable("id") Serializable id, @PathVariable("filename") String filename) throws Exception {
        Resource resource = resourceService.findById(id);
        if (resource == null) {
            throw new ServerBizException("资源不存在");
        }
        byte[] data = HttpRequest.get(resource.getUrl()).execute().bodyBytes();
        filename = resource.getName();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentLength(data.length);
        headers.setContentDispositionFormData("attachment", new String(filename.getBytes("UTF-8"), "ISO8859-1"));
        return new ResponseEntity<>(data, headers, HttpStatus.OK);
    }

}
